package cn.lzx.hrm.controller;

import cn.lzx.doc.CourseDoc;
import cn.lzx.hrm.config.HighlightResultMapper;
import cn.lzx.hrm.repository.CourseDocRepository;
import cn.lzx.query.CourseDocQuery;
import cn.lzx.util.AggsVo;
import cn.lzx.util.AjaxResult;
import cn.lzx.util.PageList;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/courseDoc")
public class CourseDocController {
    @Autowired
    private CourseDocRepository repository;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private HighlightResultMapper highlightResultMapper;

    //批量添加
    @PostMapping("/add")
    public AjaxResult batchAdd(@RequestBody List<CourseDoc> courseDocs){
        repository.saveAll(courseDocs);
        return AjaxResult.me();
    }

    //批量删除
    @PostMapping("/del")
    public AjaxResult batchDel(@RequestBody List<Long> ids){
        Iterable<CourseDoc> courseDocs = repository.findAllById(ids);
        repository.deleteAll(courseDocs);
        return AjaxResult.me();
    }

    @PostMapping("/queryCourses")
    public PageList<CourseDoc> queryPageData(@RequestBody CourseDocQuery query){
        //1创建构建器
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        //2 设置查询条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        String keyword = query.getKeyword();
        //2.1 dsl查询  以名字 适用用户等查询
        if (!StringUtils.isEmpty(keyword)){
            boolQuery.must(QueryBuilders.multiMatchQuery(keyword,"name","forUser","gradeName","tenantName","courseTypeName"));
//            boolQuery.must(QueryBuilders.matchQuery("all",keyword));
        }
        //2.2 dsl过滤  类型 机构 minprie maxprice
        Long courseTypeId = query.getCourseTypeId();
        if (courseTypeId!=null){
            boolQuery.filter(QueryBuilders.termQuery("courseTypeId",courseTypeId));
        }
        Long tenantId = query.getTenantId();
        if (tenantId!=null){
            boolQuery.filter(QueryBuilders.termQuery("tenantId",tenantId));
        }
        Integer priceMin = query.getPriceMin();
        Integer priceMax = query.getPriceMax();
        if (priceMin!=null && priceMax!=null){
            boolQuery.filter(QueryBuilders.rangeQuery("price").gte(priceMin).lte(priceMax));
        }
        builder.withQuery(boolQuery);
        //3 排序
        String sortField = query.getSortField();
        String sortFiledName = "price"; //默认按照价格
        switch (sortField.toLowerCase()){
            case "xL": sortFiledName="saleCount";break;
            case "xp": sortFiledName="onlineTime";break;
            case "pl": sortFiledName="commentCount";break;
            case "rq": sortFiledName="viewCount";break;
        }
        SortOrder defalutSortOrder = SortOrder.DESC; //默认是降序
        if (!query.getSortType().equals("desc")){ //如果不是降序就设置为升序
            defalutSortOrder = SortOrder.ASC;
        }
        builder.withSort(SortBuilders.fieldSort(sortFiledName).order(defalutSortOrder));
        //4 分页
        builder.withPageable(PageRequest.of(query.getPage()-1,query.getRows()));
        //聚合
        builder.addAggregation(AggregationBuilders.terms("tenantNameAggs").field("tenantName.keyword").size(20));
        builder.addAggregation(AggregationBuilders.terms("courseTypeNameAggs").field("courseTypeName.keyword").size(20));
        // 5 高亮查询
        HighlightBuilder.Field field = new HighlightBuilder.Field("name")
                .preTags("<b style='color:red'>")
                .postTags("</b>");
        builder.withHighlightFields(field);
        //5 封装结果
//        Page<CourseDoc> page = repository.search(builder.build());
        AggregatedPage<CourseDoc> page = elasticsearchTemplate.queryForPage(builder.build(), CourseDoc.class,highlightResultMapper);
        HashMap<String, List<AggsVo>> aggs = new HashMap<>();
        StringTerms tenantNameAggs = (StringTerms) page.getAggregation("tenantNameAggs");
        List<AggsVo> tenantNameAggsVos = getAggsVos(tenantNameAggs);
        aggs.put("tenantNameAggs",tenantNameAggsVos);
        StringTerms courseTypeNameAggs = (StringTerms) page.getAggregation("courseTypeNameAggs");
        List<AggsVo> courseTypeNameAggsVos = getAggsVos(courseTypeNameAggs);
        aggs.put("courseTypeNameAggs",courseTypeNameAggsVos);
        if (page.getTotalElements()==0) {
            return new PageList();
        }
        return new PageList<>(page.getTotalElements(),page.getContent());
    }

    private List<AggsVo> getAggsVos(StringTerms tenantNameAggs) {
        List<StringTerms.Bucket> buckets = tenantNameAggs.getBuckets();
        List<AggsVo>aggvos = buckets.stream().map(bucket -> {
            AggsVo aggsVo = new AggsVo();
            String name = bucket.getKeyAsString();
            long docCount = bucket.getDocCount();
            aggsVo.setCount(docCount);
            aggsVo.setName(name);
            return aggsVo;
        }).collect(Collectors.toList());
        return aggvos;
    }

}
